package es.mgil.whoWantsToBeAMillonaire.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.util.SparseArray;

/**
 * A music manager class to manage the music of the hole application. You can
 * get an instance of Media Player for a given raw resource, indicating an
 * optional OnCompletionListener and if the play should be with looping or not.
 * 
 * This manager algo allows to play, pause or stop the player, and finally
 * destroy it
 * 
 * @author marc
 */
public class MusicManager {
	private static SparseArray<MusicManager> musicManagerServiceMap;

	private MediaPlayer player;
	private OnCompletionListener onCompletionListener;
	private boolean looping;
	private int resourceId = -1;

	/**
	 * Get an instance of MusicManager for the given raw resource
	 */
	public static MusicManager getInstance(int resourceId,
			OnCompletionListener onCompletionListener, boolean looping) {
		if (musicManagerServiceMap == null) {
			musicManagerServiceMap = new SparseArray<MusicManager>();
		}

		if (musicManagerServiceMap.get(resourceId) == null) {
			MusicManager soundService = new MusicManager(resourceId,
					onCompletionListener, looping);
			musicManagerServiceMap.put(resourceId, soundService);
		}
		return musicManagerServiceMap.get(resourceId);
	}

	private MusicManager(int resourceId,
			OnCompletionListener onCompletionListener, boolean looping) {
		this.resourceId = resourceId;
		this.onCompletionListener = onCompletionListener;
		this.looping = looping;
	}

	/**
	 * Set a new listener to be executed when music is completed (not paused or
	 * stopped)
	 */
	public void setOnCompletionListener(OnCompletionListener listener) {
		this.onCompletionListener = listener;
		if (player == null) {
			return;
		}
		player.setOnCompletionListener(listener);
	}

	/**
	 * Start playing the player. First time will be created. Following times is
	 * used the created one
	 */
	public void startPlayer(Context context) {
		if (resourceId == -1) {
			return;
		}

		if (player == null) {
			player = MediaPlayer.create(context, resourceId);
			player.setLooping(looping);
			if (onCompletionListener != null) {
				player.setOnCompletionListener(onCompletionListener);
			}
		}

		if (!player.isPlaying()) {
			player.start();
		}
	}

	/**
	 * Check if the player is playing now
	 */
	public boolean isPlaying() {
		if (player == null) {
			return false;
		}

		return player.isPlaying();
	}

	/**
	 * Pause the player if it's playing
	 */
	public void pausePlayer() {
		if (player == null) {
			return;
		}

		if (player.isPlaying()) {
			player.pause();
		}
	}

	/**
	 * Stop the player if it's playing
	 */
	public void stopPlayer() {
		if (player == null) {
			return;
		}

		if (player.isPlaying()) {
			player.stop();
		}
		player.release();
		player = null;
	}

	/**
	 * Get the media player of this manager
	 */
	public MediaPlayer getPlayer() {
		return player;
	}

	/**
	 * Destroy the current player. First stop and release it, then remove it
	 * from the cache list
	 */
	public void destroy() {
		stopPlayer();
		musicManagerServiceMap.remove(resourceId);
	}

	/**
	 * Check if music is enabled or not for the application
	 */
	public static boolean isMusicEnabled(SharedPreferences preferences) {
		return preferences.getBoolean(PreferencesKeys.PREFERENCES_MUSIC, true);
	}

	/**
	 * Set the if the music is enabled or not
	 */
	public static void setMusicEnablement(Editor editor, boolean enabled) {
		editor.putBoolean(PreferencesKeys.PREFERENCES_MUSIC, enabled);
		editor.commit();

		if (!enabled) {
			for (int i = 0; i < musicManagerServiceMap.size(); i++) {
				MusicManager mms = musicManagerServiceMap
						.get(musicManagerServiceMap.keyAt(i));
				mms.stopPlayer();
			}
		}
	}

	/**
	 * Destroy all the players in the cache list. Execute this function before
	 * finishing the application to release all the resources
	 */
	public static void destroyAllPlayers() {
		for (int i = 0; i < musicManagerServiceMap.size(); i++) {
			MusicManager mms = musicManagerServiceMap
					.get(musicManagerServiceMap.keyAt(i));
			mms.destroy();
		}
	}

}